#include "pongClient.h"

///////////////////////////////////////////////////
// This function initualizes the games variables //
///////////////////////////////////////////////////

void init_gameState( GS *gs )
{
	gs->ball_x = (float)( SCREEN_WIDTH / 2 );
	gs->ball_y = (float)( SCREEN_HEIGHT / 2 );
	gs->paddle_x[0] = 0;
	gs->paddle_x[1] = (float)( SCREEN_WIDTH - PADDLE_WIDTH );
	gs->paddle_y[0] = (float)( SCREEN_HEIGHT / 2 );
	gs->paddle_y[1] = (float)( SCREEN_HEIGHT / 2 );
}

int pongClient()
{
	/////////////////////////////////////////////////////////
	// Here we set up a connection with the running server //
	/////////////////////////////////////////////////////////

	// Ask for server address
	sf::IPAddress serverAddress;
	std::string music;
	do
	{
		std::cout << "Type address or name of the server to connect to : ";
		std::cin  >> serverAddress;
		std::cout << "Do you want sound? 'y' = yes 'n' = no: ";
		std::cin >> music;
	}
	while (!serverAddress.IsValid());

	// Create a TCP socket for communicating with server
	sf::SocketTCP client;

	// Connect to the specified server
	if (!client.Connect(PORT, serverAddress))
		return EXIT_FAILURE;
	std::cout << "Connected to server " << serverAddress << std::endl;

	std::cout << "Waiting for other player to connect..." << std::endl;

	///////////////////////////////////////////////////////
	// We initualize the window for diplaying out images //
	///////////////////////////////////////////////////////

	// The window will be 800 by 600
	sf::RenderWindow gameWindow;
	gameWindow.Create( sf::VideoMode( SCREEN_WIDTH, SCREEN_HEIGHT ), "Networked Pong v1.0" );
	gameWindow.SetFramerateLimit( 200 );

	/////////////////////////////////////////////
	// Here we load all of our image resources //
	/////////////////////////////////////////////

	// This variable holds the game state
	GS gameState;

	init_gameState( &gameState );

	short clientDirection = 0;

	sf::Image ballImage;
	sf::Image paddleImage;
	sf::Image backgroundImage;

	sf::Sprite ballSprite;
	sf::Sprite paddleSprite[2];
	sf::Sprite backgroundSprite;

	sf::SoundBuffer Buffer;
	if (!Buffer.LoadFromFile("sounds/Breathe.mp3"))
	{
	}
	sf::Sound Sound;
	Sound.SetBuffer(Buffer);
	Sound.SetLoop(true);
	Sound.SetVolume(75.f);

	// Load the images
	if( !ballImage.LoadFromFile( "images/ball.png" ) )
	{
		return EXIT_FAILURE;
	}
	if( !paddleImage.LoadFromFile( "images/left_paddle.png" ) )
	{
		return EXIT_FAILURE;
	}
	if( !backgroundImage.LoadFromFile( "images/background.png" ) )
	{
		//return EXIT_FAILURE;
	}

	ballImage.CreateMaskFromColor( sf::Color( 0, 0, 0 ) );

	// set the sprites images
	ballSprite.SetImage( ballImage );

	paddleSprite[0].SetImage( paddleImage );

	paddleSprite[1].SetImage( paddleImage );
	paddleSprite[1].FlipX( true ); // we flip the left paddle to get the right paddle

	//backgroundSprite.SetImage( backgroundImage );

	bool running = true;

	// set to none blocking 
	client.SetBlocking( false );

	bool keyUp = true;

	bool play = true;

	while( running )
	{
		if( play == true && music.compare( "y" ) == 0 )
		{
			Sound.Play();
			play = false;
		}
		/////////////////////////////////////////////////
		// This handles the input from the client side //
		/////////////////////////////////////////////////

		sf::Event event;
		while (gameWindow.GetEvent(event))
		{
			// Close window : exit
			if (event.Type == sf::Event::Closed)
				running = false;
		}

		// Requests to move up
		if( gameWindow.GetInput().IsKeyDown( sf::Key::Up ) && keyUp == true )
		{
			clientDirection = 1;
			sf::Packet directionPacket;
			directionPacket << clientDirection;
			while( client.Send( directionPacket ) == sf::Socket::NotReady )
			{
			}
			keyUp = false;
		}
		// Requests to move down
		if( gameWindow.GetInput().IsKeyDown( sf::Key::Down ) && keyUp == true )
		{
			clientDirection = 2;
			sf::Packet directionPacket;
			directionPacket << clientDirection;
			while( client.Send( directionPacket ) == sf::Socket::NotReady )
			{
			}
			keyUp = false;
		}
		// Requests to stop moving
		if( !gameWindow.GetInput().IsKeyDown( sf::Key::Up ) && !gameWindow.GetInput().IsKeyDown( sf::Key::Down ) && keyUp == false  )
		{
			clientDirection = 0;
			sf::Packet directionPacket;
			directionPacket << clientDirection;
			while( client.Send( directionPacket ) == sf::Socket::NotReady )
			{
			}
			keyUp = true;
		}
		// ends the game
		if( gameWindow.GetInput().IsKeyDown( sf::Key::Escape ) )
		{
			running = false;
		}

		////////////////////////////////////////////////////////
		// This is where the client gets the servers feedback //
		// for whether it can move or not and game state      //
		////////////////////////////////////////////////////////

		sf::Packet gameStatePacket;
		if( client.Receive( gameStatePacket ) != sf::Socket::NotReady )
		{
			gameStatePacket >> gameState;
		}

		///////////////////////////////////////////////////////
		// Here were set the images where they need to be by //
		// pulling from the gameStatePacket					 //
		///////////////////////////////////////////////////////

		ballSprite.SetPosition( gameState.ball_x, gameState.ball_y );
		paddleSprite[0].SetPosition( gameState.paddle_x[0], gameState.paddle_y[0] );
		paddleSprite[1].SetPosition( gameState.paddle_x[1], gameState.paddle_y[1] );

		////////////////////////////////////////////////////////////////////////////////
		// Then we draw the sprites to the game window and display them to the screen //
		////////////////////////////////////////////////////////////////////////////////

		gameWindow.Draw( backgroundSprite );
		gameWindow.Draw( ballSprite );
		gameWindow.Draw( paddleSprite[0] );
		gameWindow.Draw( paddleSprite[1] );

		gameWindow.Display();
	}

	//close the client socket
	client.Close();
	return EXIT_SUCCESS;
}
